{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Nginx 边用边学\n",
    "\n",
    "Nginx 是一款HTTP和反向代理服务器，同时也是邮件代理服务器和通用TCP / UDP代理服务器，最初由Igor Sysoev（伊戈尔·塞索耶夫）编写。它已经在许多重负载的俄罗斯站点上运行多年，包括 Yandex， Mail.Ru， VK和 Rambler。根据Netcraft的数据，nginx 在2020年4月为最繁忙的站点提供了服务或代理了 25.54％的站点。以下是一些成功案例： Dropbox， Netflix， Wordpress.com， FastMail.FM。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 安装\n",
    "\n",
    "Linux下的安装，参考官方文档<http://nginx.org/en/linux_packages.html>。安装完成后，运行版本查看命令："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "nginx version: nginx/1.14.0 (Ubuntu)\r\n"
     ]
    }
   ],
   "source": [
    "!nginx -v"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 获取正在运行的 nginx 进程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  594 ?        Ss     0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;\r\n",
      "  595 ?        S      0:00 nginx: worker process\r\n",
      "  596 ?        S      0:04 nginx: worker process\r\n",
      "11918 pts/1    Ss+    0:00 /bin/sh -c ps -ax | grep nginx\r\n",
      "11920 pts/1    S+     0:00 grep nginx\r\n"
     ]
    }
   ],
   "source": [
    "!ps -ax | grep nginx"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 配置文件\n",
    "\n",
    "nginx及其模块的工作方式在配置文件中确定。默认情况下，该配置文件被命名`nginx.conf` ，并放入目录 `/usr/local/nginx/conf`， `/etc/nginx`或 `/usr/local/etc/nginx`。想要查找配置文件所在位置，可以执行："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/etc/nginx/nginx.conf\r\n"
     ]
    }
   ],
   "source": [
    "!find / -name nginx.conf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 配置文件的结构\n",
    "\n",
    "nginx由受配置文件中指定的指令控制的模块组成。伪指令分为简单伪指令和块伪指令。一个简单的指令由名称和参数组成，这些名称和参数之间用空格分隔，并以分号（;）结尾。块指令的结构与简单指令的结构相同，但是它以分号（而不是分号）结尾，并带有一组用括号（{和}）包围的附加指令。如果块指令可以在括号内包含其他指令，则称为上下文（示例： events， http， server和 location）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "user www-data;\r\n",
      "worker_processes auto;\r\n",
      "pid /run/nginx.pid;\r\n",
      "include /etc/nginx/modules-enabled/*.conf;\r\n",
      "\r\n",
      "events {\r\n",
      "\tworker_connections 768;\r\n",
      "\t# multi_accept on;\r\n",
      "}\r\n",
      "\r\n",
      "http {\r\n",
      "\r\n",
      "\t##\r\n",
      "\t# Basic Settings\r\n",
      "\t##\r\n",
      "\r\n",
      "\tsendfile on;\r\n",
      "\ttcp_nopush on;\r\n",
      "\ttcp_nodelay on;\r\n",
      "\tkeepalive_timeout 65;\r\n",
      "\ttypes_hash_max_size 2048;\r\n",
      "\t# server_tokens off;\r\n",
      "\r\n",
      "\t# server_names_hash_bucket_size 64;\r\n",
      "\t# server_name_in_redirect off;\r\n",
      "\r\n",
      "\tinclude /etc/nginx/mime.types;\r\n",
      "\tdefault_type application/octet-stream;\r\n",
      "\r\n",
      "\t##\r\n",
      "\t# SSL Settings\r\n",
      "\t##\r\n",
      "\r\n",
      "\tssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE\r\n",
      "\tssl_prefer_server_ciphers on;\r\n",
      "\r\n",
      "\t##\r\n",
      "\t# Logging Settings\r\n",
      "\t##\r\n",
      "\r\n",
      "\taccess_log /var/log/nginx/access.log;\r\n",
      "\terror_log /var/log/nginx/error.log;\r\n",
      "\r\n",
      "\t##\r\n",
      "\t# Gzip Settings\r\n",
      "\t##\r\n",
      "\r\n",
      "\tgzip on;\r\n",
      "\r\n",
      "\t# gzip_vary on;\r\n",
      "\t# gzip_proxied any;\r\n",
      "\t# gzip_comp_level 6;\r\n",
      "\t# gzip_buffers 16 8k;\r\n",
      "\t# gzip_http_version 1.1;\r\n",
      "\t# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;\r\n",
      "\r\n",
      "\t##\r\n",
      "\t# Virtual Host Configs\r\n",
      "\t##\r\n",
      "\r\n",
      "\tinclude /etc/nginx/conf.d/*.conf;\r\n",
      "\tinclude /etc/nginx/sites-enabled/*;\r\n",
      "}\r\n",
      "\r\n",
      "\r\n",
      "#mail {\r\n",
      "#\t# See sample authentication script at:\r\n",
      "#\t# http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript\r\n",
      "# \r\n",
      "#\t# auth_http localhost/auth.php;\r\n",
      "#\t# pop3_capabilities \"TOP\" \"USER\";\r\n",
      "#\t# imap_capabilities \"IMAP4rev1\" \"UIDPLUS\";\r\n",
      "# \r\n",
      "#\tserver {\r\n",
      "#\t\tlisten     localhost:110;\r\n",
      "#\t\tprotocol   pop3;\r\n",
      "#\t\tproxy      on;\r\n",
      "#\t}\r\n",
      "# \r\n",
      "#\tserver {\r\n",
      "#\t\tlisten     localhost:143;\r\n",
      "#\t\tprotocol   imap;\r\n",
      "#\t\tproxy      on;\r\n",
      "#\t}\r\n",
      "#}\r\n"
     ]
    }
   ],
   "source": [
    "!cat /etc/nginx/nginx.conf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 虚拟主机的常见配置\n",
    "\n",
    "虚拟主机的配置，需要指定监听端口，主机域名，以及网站根目录位置。\n",
    "\n",
    "```\n",
    "server {\n",
    "    listen 80;\n",
    "    server_name nav.yangzh.cn; #域名，例如：www.example.com。\n",
    "    location / {\n",
    "        root /home/yangzh/repos/nav.yangzh.cn/public;\n",
    "        index index.html index.htm;\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 为虚拟主机配置SSL证书\n",
    "\n",
    "1. 首先申请SSL证书，可到阿里云等服务商申请免费证书，一般期限1年，到期后再重新申请。\n",
    "1. 将申请到的证书，上传到服务器的某个目录，如`/etc/nginx/conf.d/cert`。\n",
    "1. 在虚拟主机的配置文件中，加入必要配置信息：`ssl_certificate` 和 `ssl_certificate_key`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "server {\n",
    "    listen 443 ssl;\n",
    "    server_name nav.yangzh.cn;\n",
    "    ssl_certificate /etc/nginx/conf.d/cert/3825312_nav.yangzh.cn.pem;\n",
    "    ssl_certificate_key /etc/nginx/conf.d/cert/3825312_nav.yangzh.cn.key;\n",
    "    ssl_session_timeout 5m;\n",
    "    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;\n",
    "    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\n",
    "    ssl_prefer_server_ciphers on;\n",
    "\n",
    "    location / {\n",
    "        root /home/yangzh/repos/nav.yangzh.cn/public;\n",
    "        index index.html index.htm;\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 设置http请求自动跳转https\n",
    "\n",
    "在需要跳转的HTTP站点下添加rewrite语句，实现HTTP访问自动跳转到HTTPS页面。\n",
    "\n",
    "```\n",
    "server {\n",
    "    listen 80;\n",
    "    server_name nav.yangzh.cn; #将localhost修改为您证书绑定的域名，例如：www.example.com。\n",
    "    rewrite ^(.*)$ https://$host$1 permanent; #将所有http请求通过rewrite重定向到https。\n",
    "    location / {\n",
    "        root /home/yangzh/repos/nav.yangzh.cn/public;\n",
    "        index index.html index.htm;\n",
    "    }\n",
    "}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 排查错误\n",
    "\n",
    "如果某些操作无法按预期工作，则可以尝试通过日志文件（access.log和 error.log文件）查找原因。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 参考资料\n",
    "1. <http://nginx.org/en/>\n",
    "1. <https://help.aliyun.com/document_detail/98728.html?spm=5176.2020520163.0.0.42d1uhxxuhxxdT#title-4mj-mh9-ap3>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {
    "height": "209px",
    "width": "250px"
   },
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
